package models

import (
	"bigdevops/src/common"
	"bigdevops/src/config"
	"encoding/json"
	"fmt"
	"go.uber.org/zap"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/intstr"
	"os"
	"path/filepath"
	"strings"
)

var (
	k8sCluster01KubeconfigC = `

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EZ3hNekV5TXpJd05Wb1hEVE16TURneE1ERXlNekl3TlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTXN3CkMyUHA2dWM1UTFocTBVc042SHk0dG1naUM5dHZFUUJ2K0hZa1ZFN3I4dnEvZ1lnQ1c4MlJ3Y3hJYU8rd2JiWEgKRmVYWm12MzNxRDFjUGtFREJQZFlXUDJHRnRSMFQ1MnY0S2l2VzR1Wkkvc3o5b1Z3dzNNTXVURjVnRU5sR2tsUgpHOFJHM3ZBZkkrd0NXMVlZMFJQWFlXZFNodm5GN0tQblJwZTd3M2x4blRRTkJDYUNEZEVuVnZFWVU4ckN2eVcxCi9raTF4UDlUMEhNRDdob1lqOVBtRGtoeW9XbEIyQWFDdjdjRlBvdFZuTnVuWEVZTFUzWWxnYTVlLzNER2dPcWkKTllxRXJLR0dicm1VTWVGcTdFVWQ0SVExSks1RnF0ZnNnZWs0OU45b3NmWEVMcUM1VXM3V1hrVFVnSW9laGVxZApqd0ovbnIxN0hpeUFwUjNHY3RFQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZGUUI5ODZjWS83QUltMkNKNC9zYnlRVFNLTXhNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBR2pGTkxzQmNwT2Q0WDU3QUNOVwprWkRWVWdLeU1MM1h1S3lGclFWZkNrNzBCK3E4TFkvbjczN3V2emVmZlZ6Rk9PS3MrQzBrM0c0ZTIwMmp2QWw1CnVTOXl0cHp2MnhiT1d0NW1tb0hUakRTcTc3eWsrR1dtMkVrOEhVbTM4ZlFtRlRGRHNJQ2NnT0w0dVhFdU9ibzkKTlIvSUZMMjFhRnFJYjZweFNJMGx4UlowVFVTS0ZROTNFQXRDWGJIYXNzM2ljbjdqalBNZE1XdkVxRkFsb3FwWgpKQ1lHb0U0TG5kUlBRRks3MDd2L2UrbHBXczB4OWpCZTNYUXNQaWRnQUJLOGZFSThYaW00NnVjZDd1ZDRMK2dTCmZmbjgvbVlaSmM3VGlXc0hYQW5HM1l4Y2ZTVGRwbjM3eTFCc3pvUXh2R3FHMTlWWVZrUUlmMVc1VGFZUUFJOTEKczJZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://192.168.0.81:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURJVENDQWdtZ0F3SUJBZ0lJQmpnYWMzTUlSSll3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TXpBNE1UTXhNak15TURWYUZ3MHlOREE0TVRJeE1qTXlNRGRhTURReApGekFWQmdOVkJBb1REbk41YzNSbGJUcHRZWE4wWlhKek1Sa3dGd1lEVlFRREV4QnJkV0psY201bGRHVnpMV0ZrCmJXbHVNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXlPWWc3OEh3dE1zUGxDN1oKOVBGRnh4OXhkNndvOU9XVkQwZ2t5RjAycnhPcWoweW1vREMyY1loQ1pKdDJYRHJEVVo1dVo3dHUvSXFEVFBQZwp6cUZicnMvZFdxQzdUUUI4M3N2U0tRRTNIMncvaWVFM3JjZlFNL3YxTHpudWw4cEM0SDhOUkdXeUNIRVl0UjVrCjJ2N1gwdXlFelE1Y3ZyRCtrZ0tLTkQ2eHFHaklXdTNwUjVTbFVRWFMxN1cxM01yYjh4MjFteVZTS0R3U0drQzMKeXl6dGhNQWtNcmY0Vm9Zd1luN2lFK2w3K0dVK0RpUys1YnllODBPYWIxcCtYdlJyWCtQUXF1dHJNUXVxQTdxVgpGY05PNEhyNkNFbDZrbW1PNWUydmhvdkNTQ3l0T3Vrcm1EdnF4UzdTRzV0amJ0U01oRVU3dTh0Y2xadFNuQzQ2CkNwUkFyUUlEQVFBQm8xWXdWREFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUgKQXdJd0RBWURWUjBUQVFIL0JBSXdBREFmQmdOVkhTTUVHREFXZ0JSVUFmZk9uR1Ard0NKdGdpZVA3RzhrRTBpagpNVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBU000dWFVV2dFT1o3eWEzb25zTlZ5ekxBSWl2V1FGS3hFZ2hYCmZxMDA2S2ZGbWoxdzE3ZU5IT1JnNXVNNFl6TnVvayt6ak16OEVJa3FuTzNuUUhXbXE4QVRjbVBpUlJ0SmVQSmMKd0VYUE1zTG5salI1RmVqTFFCa1JjK0NXQjBOZ0c0TDh1Q3AreHhFcDZWZUpVTzlwK3M0U2RtVmFRUy85OE9XdwpXTThNeXBZL0V2cm0xcEREQWRpZUVFZ3hOQnZrVUFKVVR6dExvUzhTVHZ1Y0pJTXp6NzErRi9ybFlTaldLKzhlCk92eTB3eDgvdlFBK1ZiWnMzZ1BLNGJoY0ptQ0xmdlpXc0RnRzMwbUcwdWlFSU5qL1ozUFJPeE9nS2NwL0hvM1oKdHVDWFRJMjhzdlg4cFZvbkVtVk5nZEt5WjZxS1hrdU10N2t4bTFlM3NQem9nR0FPcmc9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb2dJQkFBS0NBUUVBeU9ZZzc4SHd0TXNQbEM3WjlQRkZ4eDl4ZDZ3bzlPV1ZEMGdreUYwMnJ4T3FqMHltCm9EQzJjWWhDWkp0MlhEckRVWjV1Wjd0dS9JcURUUFBnenFGYnJzL2RXcUM3VFFCODNzdlNLUUUzSDJ3L2llRTMKcmNmUU0vdjFMem51bDhwQzRIOE5SR1d5Q0hFWXRSNWsydjdYMHV5RXpRNWN2ckQra2dLS05ENnhxR2pJV3UzcApSNVNsVVFYUzE3VzEzTXJiOHgyMW15VlNLRHdTR2tDM3l5enRoTUFrTXJmNFZvWXdZbjdpRStsNytHVStEaVMrCjVieWU4ME9hYjFwK1h2UnJYK1BRcXV0ck1RdXFBN3FWRmNOTzRIcjZDRWw2a21tTzVlMnZob3ZDU0N5dE91a3IKbUR2cXhTN1NHNXRqYnRTTWhFVTd1OHRjbFp0U25DNDZDcFJBclFJREFRQUJBb0lCQUhlOUdjSnM4RitCYSs2aApJZzBveExNUzNaazdSa240a0NoRWtvL05adXRncUZheWs5bUVUeWxKMG5DT2JEUTZYZkhHb1AwNHJNVGVkYldtCjRjV21UTFBiZG80dW9KUWJoMUZ2WC9wS25DVWhhcGx1WDdZM0VyUDVKMENYb2NwY3BoR1NDRUZNNzVpeWQ4eHoKcWg4UXAyZ3l5bEJCa0N1ajZJYno5cFYvREhwWHN6OVVGdmhKRkYyRnMwMzRLemFxM0NmcXlzbGZRTHdzQlhiNQp0S0RFdW9yNE5OOW5sMVFKbXU3TXNVZUVHSUp1WlBYZUdSdmhYS3pxQ1FldXBzL0M4Mlh2VnNqUmdpL295WnVPCm9nL0hNL1dRU0dkMlp4Tnc5OERNaE5WUUdPclpQOUJQZnl5VFVZRC9jUWRRUkg1MEhXbUZRSU9iZmoxVEVJbjEKdE9QbjVjMENnWUVBMzl3UkhoeERJbVdkSUZPcGhnQ3Y5Z01lR0dvSGFrY3NRNEVWbkpqNDREaXFXWGpXN0todgpmNy9WODE3bUo2dmhSclhJQ1VnOC9yU3BTekJKUWxIaEo1Mkd4OGExN1RZWE5PdzBDaldmUzQ2US9SWVpUTThzClRkMTJuN3ZLS3d2U0dOc0kxR3JLN2wrTlBVbW96aTM4dG9peGNKa1JMaWpHQVJ6MjM0b2FhQ01DZ1lFQTViNGsKN2c4NHdvSDFBb2NEYmdmYnJLSFB0c0EwOFI0Ryt6cmxpOWN4dDN1cFF0cXI2S09XL1FaQk1wUFF0cmJ4c2R3SgpBcVk3VXhxWkNkbDNEVTVwZ3lmSGlXS2VJeTQweVY5R2lrRzlLSll5Yno4MEtxR0UrTGdxWHZVRUVrK1dtaHIvCjkxd1dvL3ZFWlN6YXAvcSs1STNvU1JoVk0xclZtNHg2eDlEcldPOENnWUFaQTRNYUpUaFBNS0dGQ2pRb0dBMlIKWkxuSktwZlhoVXBwNUpPZ291czBTc0NtTEwxL1JqYm5SRzFJdTNMbVBldDNOanE2NXNxQi8zZm5RZWI5dFI1KwppYmlVdkJ4NS9CQk54cEx1RFIzV21JQ1U5eEl1cGZ1aVc3dTBqNHhBa1JxUjBtL0RKSWUyYVJEa0owWG9lL1VBCkJIZ25SOE5Hc0NHbjRDK3B2TW5FbHdLQmdFdUc1QXNqRSt6VjNsOHpWWXhScHdVc3VPV0NjS1VuMHZHNm5nWUgKKzc4dk55alVUSm1SVml6ZVpvYWpFNFZOeFUxTVllWHVFaWl5NE1iZEtBZEcxT2NhSjczaG5zMC8vbmlKQ3Q2ZQoxL25FenRYRnVIZWZXK0NNWXRtT3dRVG9CMEdvU0tmZ0xVMUJrb0lVYWRtNVZCSTlHTFVXKzhPRFJCLzc0YzFZCndGWWZBb0dBT2pRd0RkeWg0L01YTzA5QWpOQ0hzRTVnNnJ4bHhtclRiTzFHZFVSckFOWUg4RnB5Q2gwUWxUWloKV0kyUldXdU50RUdPNDVsN08rVXJINGNkUFR6MDBmbkhlU3czVUVJeklxQ0I3UCtXc005R2tCNC9iMkFDQXJNZwpmandwK0h1eFNSemQ2M1pTT2dPYXZCb0cwVnF4TXhiTTNkNDdoNGFlM0pHNUJWM1o2T3M9Ci0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==

`
	yamlTemplate1 = `

apiVersion: apps/v1	#与k8s集群版本有关，使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment	#该配置的类型，我们使用的是 Deployment
metadata:	        #译名为元数据，即 Deployment 的一些基本属性和信息
  name: VAR_NGX_DEP_NAME	#Deployment 的名称
  labels:	    #标签，可以灵活定位一个或多个资源，其中key和value均可自定义，可以定义多组，目前不需要理解
    app: nginx	#为该Deployment设置key为app，value为nginx的标签
spec:	        #这是关于该Deployment的描述，可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1	#使用该Deployment创建一个应用程序实例
  selector:	    #标签选择器，与上面的标签共同作用，目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:	    #这是选择或创建的Pod的模板
    metadata:	#Pod的元数据
      labels:	#Pod的标签，上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:	    #期望Pod实现的功能（即在pod中部署）
      containers:	#生成container，与docker中的container是同一种
      - name: nginx	#container的名称
        image: nginx:1.7.9	#使用镜像nginx:1.7.9创建container，该container默认80端口可访问
---

apiVersion: v1
kind: ServiceAccount
metadata:
  name: VAR_SA_NAME
  namespace: default
`
)

func MockK8s(sc *config.ServerConfig) {
	sc.Logger.Info("MockK8s函数开始")
	kubeConfigContents := []string{}
	kubeConfigContentMap := map[string]string{}
	kubeConfigNames := []string{}
	// 遍历kube-configs 文件夹 读取kubeconfig文件
	entries, err := os.ReadDir("./kube-configs")
	if err != nil {
		sc.Logger.Error("MockK8s遍历读取kube-configs目录错误",
			zap.Error(err),
		)
		//return
	}
	pwd, _ := os.Getwd()

	for _, entry := range entries {
		info, err := entry.Info()
		if err != nil {
			continue

		}
		filename := filepath.Join(pwd, "kube-configs", info.Name())
		content, err := os.ReadFile(filename)
		if err != nil {
			sc.Logger.Error("MockK8s遍历读取kube-configs-ReadFile错误",
				zap.Error(err),
				zap.Any("info.Name()", info.Name()),
			)
		}
		kubeConfigContentMap[info.Name()] = string(content)
		kubeConfigNames = append(kubeConfigNames, info.Name())
		kubeConfigContents = append(kubeConfigContents, string(content))
	}

	// 造脚本
	num := len(kubeConfigNames)
	// 多个集群并发执行
	//var wg sync.WaitGroup
	//wg.Add(num)
	for i := 0; i < num; i++ {
		//
		i := i
		mIndex := i
		if mIndex >= len(kubeConfigContents) {
			mIndex = len(kubeConfigContents) - 1
		}

		tmp := K8sCluster{
			Name:                 kubeConfigNames[mIndex],
			NameZh:               fmt.Sprintf("集群-%v", i),
			UserID:               1,
			ActionTimeoutSeconds: i + 1,
			Env:                  common.RUN_ENV_TYPE_ARRAY[common.Frn(len(common.RUN_ENV_TYPE_ARRAY)-1)],
			KubeConfigContent:    kubeConfigContents[mIndex],
		}
		tmp.SetDefaultResource()
		tmp.FillDefaultData()
		tmp.CreateOne()
		//go func() {
		//	tmp := K8sCluster{
		//		Name:                 kubeConfigNames[mIndex],
		//		NameZh:               fmt.Sprintf("集群-%v", i),
		//		UserID:               1,
		//		ActionTimeoutSeconds: i + 1,
		//		Env:                  common.RUN_ENV_TYPE_ARRAY[common.Frn(len(common.RUN_ENV_TYPE_ARRAY)-1)],
		//		KubeConfigContent:    kubeConfigContents[mIndex],
		//	}
		//	tmp.SetDefaultResource()
		//	tmp.FillDefaultData()
		//	tmp.CreateOne()
		//	wg.Done()
		//}()

	}
	//wg.Wait()

	sc.Logger.Info("MockK8s函数造集群结束")
	clusters, _ := GetK8sClusterAll()
	go func() {
		// 构造节点
		num = 30
		// 先获取所有集群

		for _, cluster := range clusters {
			cluster := cluster
			//nodes := []corev1.Node{}

			_, kClientSet, err := common.GenK8sClientSetByKubeConfigContent(cluster.KubeConfigContent)
			if err != nil {
				continue
			}
			if kClientSet == nil {
				continue
			}
			ctx2, cancel2 := common.GenTimeoutContext(cluster.ActionTimeoutSeconds)
			defer cancel2()
			_, err = kClientSet.CoreV1().Namespaces().List(ctx2, metav1.ListOptions{})
			if err != nil {
				continue
			}

			for i := 0; i < num; i++ {

				node := &corev1.Node{
					TypeMeta:   metav1.TypeMeta{},
					ObjectMeta: metav1.ObjectMeta{},
					Spec:       corev1.NodeSpec{},
					Status:     corev1.NodeStatus{},
				}

				node.Name = fmt.Sprintf("%v-mock-node-%v",
					strings.ReplaceAll(cluster.Name, "_", "-"),
					i,
				)
				ctx1, cancel1 := common.GenTimeoutContext(cluster.ActionTimeoutSeconds)
				defer cancel1()
				kClientSet.CoreV1().Nodes().Create(ctx1, node, metav1.CreateOptions{})

			}

		}
		sc.Logger.Info("MockK8s函数造 构造节点结束")
	}()

	// 构造模板
	num = 1
	for i := 0; i < num; i++ {

		t := K8sYamlTemplate{
			Name:    fmt.Sprintf("yaml-template-%v", i),
			UserID:  1,
			Content: yamlTemplate1,
		}
		t.CreateOne()

	}
	// 构造任务
	for _, cluster := range clusters {
		cluster := cluster
		t := K8sYamlTask{
			Name:        fmt.Sprintf("yaml-task-%v-%v", 1, cluster.Name),
			UserID:      1,
			TemplateId:  1,
			ClusterName: cluster.Name,
			Variables: []string{
				fmt.Sprintf(`VAR_NGX_DEP_NAME=nginx-%v`, cluster.Name),
				fmt.Sprintf(`VAR_SA_NAME=sa-%v`, cluster.Name),
			},
			Status: common.K8S_YAMLTASK_STATUS_PENDING,
		}
		t.CreateOne()
	}

	// 构造项目和应用

	num = 2
	for i := 0; i < num; i++ {
		clusterName := clusters[i].Name
		projectName := fmt.Sprintf("project-mock-%v", i)
		apps := []K8sApp{}

		appName := "k8s-app-busybox"

		appBusyBox := K8sApp{
			Name:       appName,
			Cluster:    clusterName,
			TreeNodeId: 5,
			UserID:     1,

			//K8sInstances: ins,
		}

		//ins := []K8sInstance{
		//	{
		//		Name:    fmt.Sprintf("k8s-ins-%v-%v", appName, i),
		//		UserID:  1,
		//		Cluster: clusterName,
		//	},
		//}
		//app.SetDefaultResource()

		appBusyBox.Envs = []string{"k1=v1", "k2=v1"}
		appBusyBox.Labels = []string{"l1=v1", "l2=v1"}
		//app.Commands = "sh -c 'echo The app is running! && sleep infinity ' "
		appBusyBox.Commands = []string{
			"sh",
			"-c",
			"echo The app is running! && sleep infinity",
		}

		appBusyBox.VolumeJsonFront = []OneVolume{
			{
				Type:         common.K8S_VOLUME_TYPE_HOSTPATH,
				Name:         "log",
				MountPath:    "/log",
				SubPath:      "sub",
				HostPathPath: fmt.Sprintf("/data/%v", appName),
				HostPathType: string(corev1.HostPathDirectoryOrCreate),
			},
			{
				Type:      common.K8S_VOLUME_TYPE_CONFIGMAP,
				Name:      "cm",
				MountPath: "/cm",
				CmName:    "cm-demo01",
			},
		}
		vs, _ := json.Marshal(appBusyBox.VolumeJsonFront)

		appBusyBox.VolumeJson = string(vs)
		appBusyBox.PortJsonFront = []corev1.ServicePort{
			{
				Name:       "http",
				Protocol:   "TCP",
				Port:       80,
				TargetPort: intstr.FromInt32(80),
			},
		}
		ps, _ := json.Marshal(appBusyBox.PortJsonFront)
		appBusyBox.Namespace = "default"
		appBusyBox.PortJson = string(ps)

		appNginx := K8sApp{}

		appBytes, _ := json.Marshal(&appBusyBox)
		json.Unmarshal([]byte(appBytes), &appNginx)
		appNginx.Name = "k8s-app-nginx"
		appNginx.Commands = nil

		// 再来新建一个go-app-01
		appGo01 := K8sApp{}
		appBytes, _ = json.Marshal(&appBusyBox)
		json.Unmarshal([]byte(appBytes), &appGo01)
		appGo01.Name = "k8s-app-go01"
		appGo01.Commands = []string{"/bin/go-app-01"}

		appGo01.PortJsonFront = []corev1.ServicePort{
			{
				Name:       "http",
				Protocol:   "TCP",
				Port:       8080,
				TargetPort: intstr.FromInt32(8080),
			},
		}
		ps, _ = json.Marshal(appGo01.PortJsonFront)
		appGo01.PortJson = string(ps)

		apps = append(apps, appBusyBox)
		apps = append(apps, appNginx)
		apps = append(apps, appGo01)

		kt := K8sProject{
			Name:       projectName,
			Cluster:    clusterName,
			NameZh:     projectName,
			TreeNodeId: 4,
			UserID:     1,
			K8sApps:    apps,
		}

		kt.CreateOne()

	}
}
